package com.hudilao.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hudilao.common.BaseContext;
import com.hudilao.common.R;
import com.hudilao.controller.CartController;
import com.hudilao.dto.*;
import com.hudilao.entity.*;
import com.hudilao.exception.CustomException;
import com.hudilao.exception.OrderException;
import com.hudilao.mapper.*;
import com.hudilao.service.*;
import com.hudilao.util.WechatPayUtil;
import com.hudilao.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.DigestUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;


@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    @Autowired
    private CartService cartService;

    @Autowired
    private CustomerService customerService;

    @Autowired
    private CustomerMembershipService customerMembershipService;

    @Autowired
    private OrderDetailService orderDetailService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private DiningTableMapper diningTableMapper;

    @Autowired
    private CustomerMapper customerMapper;

    @Autowired
    private WechatPayUtil wechatPayUtil;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private CustomerMembershipMapper customerMembershipMapper;

    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Autowired
    private StockService stockService;

    @Autowired
    private SetmealDishService setmealDishService;

    @Autowired
    private OrderReviewService orderReviewService;

    @Autowired
    private DishService dishService;

    @Autowired
    private SetmealService setmealService;

    @Autowired
    private DiningTableService diningTableService;

    /**
     * 用户下单
     * @param orderSubmitDTO
     */
    @Transactional
    public OrderSubmitVO submit(OrderSubmitDTO orderSubmitDTO, long customerId) {

        //处理异常 传来的数据为空？
        if(orderSubmitDTO == null){
            throw new OrderException("订单数据为空，无法下单");
        }

        //查询当前用户购物车
        LambdaQueryWrapper<Cart> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Cart::getCustomerId,customerId);
        List<Cart> cartList = cartService.list(queryWrapper);

        //购物车为空？
        if(cartList == null || cartList.size() == 0){
            throw new OrderException("购物车为空，不能下单");
        }

        //查询用户数据
        Customer customer = customerService.getById(customerId);
        //DiningTable diningTable = diningTableService.getById()

        AtomicInteger amount = new AtomicInteger(0);

        long orderId = IdWorker.getId();


        List<OrderDetail> orderDetails = cartList.stream().map((item) -> {
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setOrderId(orderId);
            orderDetail.setItemId(item.getItemId());
            orderDetail.setItemName(item.getName());
            if (item.getType() == 1) {
                // 该订单详情为菜品详情
//                orderDetail.setDishId(item.getItemId());
//                orderDetail.setDishName(item.getName());
                orderDetail.setType(1);

                //修改菜品库存
                stockService.reduceStockAfterOrder(item.getItemId(),item.getNumber());

            } else if (item.getType() == 2) {
                // 该订单详情为套餐详情
//                orderDetail.setSetmealId(item.getItemId());
//                orderDetail.setSetmealName(item.getName());
                orderDetail.setType(2);

                // 查询套餐中的菜品并更新库存
                LambdaQueryWrapper<SetmealDish> setmealDishQueryWrapper = new LambdaQueryWrapper<>();
                setmealDishQueryWrapper.eq(SetmealDish::getSetmealId, item.getItemId());
                List<SetmealDish> setmealDishes = setmealDishService.list(setmealDishQueryWrapper);

                for (SetmealDish setmealDish : setmealDishes) {
                    stockService.reduceStockAfterOrder(setmealDish.getDishId(), setmealDish.getCopies() * item.getNumber());
                }
            }
            orderDetail.setQuantity(item.getNumber());
            orderDetail.setAmount(item.getAmount());
            amount.addAndGet(item.getAmount().multiply(new BigDecimal(item.getNumber())).intValue());


            return orderDetail;
        }).collect(Collectors.toList());

        //向order表插入一条数据
        Order order = new Order();
        order.setId(orderId);
        order.setCustomerId(customerId);
        order.setStatus(Order.SUBMITTED);
        order.setTableNumber(diningTableMapper.getTableNumberByCustomerID(customerId));
        order.setAmount(new BigDecimal(amount.get()));
        this.save(order);


        //向order_detail表插入n条数据
        orderDetailService.saveBatch(orderDetails);

        //封装VO返回结果
        OrderSubmitVO orderSubmitVO = OrderSubmitVO.builder()
                .orderId(orderId)
                .amount(new BigDecimal(amount.get()))
                .createTime(order.getCreateTime())
                .build();

        return orderSubmitVO;

    }

    /**
     * 用户付款
     * @param orderPaymentDTO
     * @return
     */
    public OrderPaymentVO pay(OrderPaymentDTO orderPaymentDTO) throws Exception{



        //获取当前客户
        long customerId = BaseContext.getCurrentId();
        Customer customer = customerMapper.getById(customerId);

        //调用微信支付接口
        JSONObject jsonObject = wechatPayUtil.pay(
                orderPaymentDTO.getOrderId(),
                new BigDecimal(0),
                "湖底捞订单",
                customer.getOpenid()
        );

        if (jsonObject.getString("code") != null && jsonObject.getString("code").equals("ORDERPAID")) {
            throw new OrderException("该订单已支付");
        }



        OrderPaymentVO orderPaymentVO = jsonObject.toJavaObject(OrderPaymentVO.class);
        orderPaymentVO.setPackageStr(jsonObject.getString("package"));

        return orderPaymentVO;
    }

    /**
     * 用户付款后更新订单状态，付款方式，完成时间
     * @param id
     * @param status
     * @param paymentMethod
     * @param completeTime
     */
    public void updateByIdAfterPay(Long id,Integer status, Integer paymentMethod, LocalDateTime completeTime){
        orderMapper.updateByIdAfterPay(id,status,paymentMethod,completeTime);
    }

    /**
     * 用户使用余额付款
     * @param orderPaymentDTO include{orderId,paymentCode,paymentMethod}
     * @return
     */
    @Transactional
    public R<OrderBalancePaymentVO> payByBalance(OrderPaymentDTO orderPaymentDTO){

        //确定当前用户
        long customerId = BaseContext.getCurrentId();

        //余额支付
        //查询当前会员信息
        LambdaQueryWrapper<CustomerMembership> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CustomerMembership::getCustomerId,customerId);
        CustomerMembership customerMembership = customerMembershipService.getOne(queryWrapper);

        //判断支付密码
        String password = orderPaymentDTO.getPaymentCode();
        password = DigestUtils.md5DigestAsHex(password.getBytes());
        //密码比对
        if(!customerMembership.getPassword().equals(password)){
            return R.error("支付密码错误");
        }


        //根据订单号查询订单
        Order order = orderService.getById(orderPaymentDTO.getOrderId());
        if(order == null){
            return R.error("订单不存在");
        }

        //订单已支付
        if(order.getStatus() == Order.PAID){
            return R.error("该订单已支付，请勿重复支付");
        }


        //查询该笔订单应付金额
        BigDecimal orderAmount = order.getAmount();

        // 查询用户余额
        BigDecimal customerBalance = customerMembership.getBalance();

        // 确认用户余额是否足够支付
        if (customerBalance.compareTo(orderAmount) < 0) {
            return R.error("余额不足");
        }

        //确认支付
        customerMembership.setBalance(customerBalance.subtract(orderAmount));

        //修改订单状态
        // 修改订单状态为已支付
        order.setStatus(Order.PAID);
        order.setPaymentMethod(0);
        order.setCompleteTime(LocalDateTime.now());

        try {
            // 更新用户余额和订单状态为原子操作
            // 扣除用户余额
            customerMembershipService.updateCustomerBalance(customerMembership.getId(), customerMembership.getBalance());
            this.updateByIdAfterPay(
                    order.getId(),
                    order.getStatus(),
                    order.getPaymentMethod(),
                    order.getCompleteTime()
            );

            //更新餐桌状态
            diningTableService.updateStatusAfterPayment(customerId);
        } catch (Exception e) {
            // 捕获任何异常并回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return R.error("支付失败，请稍后再试");
        }

        //返回支付结果
        OrderBalancePaymentVO orderBalancePaymentVO = OrderBalancePaymentVO.builder()
                .balance(customerMembership.getBalance())
                .build();

        return R.success(orderBalancePaymentVO);
    }

    /**
     * 根据用户id获取其历史订单
     * @param customerId
     * @return
     */
    public List<OrderHistoryVO> getOrdersById(long customerId){

        //获取历史订单
        List<Order> orders = orderMapper.getOrdersById(customerId);
        List<OrderHistoryVO> orderHistoryVOList = new ArrayList<>();

        for(Order order: orders){



            //根据订单获取订单详情
            List<OrderDetail> orderDetails = orderDetailMapper.getOrderDetailsByOrderId(order.getId());

            List<OrderHistoryDetailVO> orderHistoryDetailVOList = new ArrayList<>();

            for (OrderDetail orderDetail : orderDetails) {
                OrderHistoryDetailVO orderHistoryDetailVO = OrderHistoryDetailVO.builder()
                        .itemId(orderDetail.getItemId())
                        .name(orderDetail.getItemName())
                        .amount(orderDetail.getAmount())
                        .quantity(orderDetail.getQuantity())
                        .build();
                orderHistoryDetailVOList.add(orderHistoryDetailVO);
            }
            OrderHistoryVO orderHistoryVO = OrderHistoryVO.builder()
                    .orderId(order.getId())
                    .tableNumber(order.getTableNumber())
                    .totalAmount(order.getAmount())
                    .status(order.getStatus())
                    .createTime(order.getCreateTime())
                    .orderHistoryDetailDTOS(orderHistoryDetailVOList)
                    .build();

            orderHistoryVOList.add(orderHistoryVO);
        }

        //获取订单详情

        return orderHistoryVOList;//orderMapper.getOrdersById(customerId);
    }

    @Override
    public OrderHistoryVO getOrderById(long orderId) {
        //获取该订单
        Order order = orderService.getById(orderId);

        //根据订单获取订单相关评论
        String reviewText = orderReviewService.getReviewTextByOrderId(order.getId());
        String merchantReply = orderReviewService.getReviewReplyByOrderId(order.getId());

        //根据订单获取订单详情
        List<OrderDetail> orderDetails = orderDetailMapper.getOrderDetailsByOrderId(order.getId());
        List<OrderHistoryDetailVO> orderHistoryDetailVOList = new ArrayList<>();

        for (OrderDetail orderDetail : orderDetails) {
            String image = null;
            if(orderDetail.getType()==1){
                LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(Dish::getId,orderDetail.getItemId());
                Dish dish = dishService.getOne(queryWrapper);
                image = dish.getImage();
            }else if(orderDetail.getType()==2){
                LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(Setmeal::getId,orderDetail.getItemId());
                Setmeal setmeal = setmealService.getOne(queryWrapper);
                image = setmeal.getImage();
            }
            OrderHistoryDetailVO orderHistoryDetailVO = OrderHistoryDetailVO.builder()
                    .itemId(orderDetail.getItemId())
                    .name(orderDetail.getItemName())
                    .amount(orderDetail.getAmount())
                    .quantity(orderDetail.getQuantity())
                    .image(image)
                    .build();
            orderHistoryDetailVOList.add(orderHistoryDetailVO);
        }

        OrderHistoryVO orderHistoryVO = OrderHistoryVO.builder()
                .orderId(order.getId())
                .tableNumber(order.getTableNumber())
                .totalAmount(order.getAmount())
                .status(order.getStatus())
                .createTime(order.getCreateTime())
                .orderHistoryDetailDTOS(orderHistoryDetailVOList)
                .reviewText(reviewText)
                .merchantReply(merchantReply)
                .build();


        return orderHistoryVO;
    }

    /**
     * 用户评价后更新订单
     * @param id
     */
    public void updateStatusByIdAfterReview(long id,Integer status) {
        orderMapper.updateByIdAfterReview(id,status);
    }


    //管理端实现

    /**
     * 订单管理
     * 订单分页查询
     * @param page
     * @param pageSize
     * @param username
     */
    @Override
    public Page<OrderDTO> getOrdersByUsername(int page, int pageSize, String username) {

        //构建分页查询page
        Page<OrderDTO> pageInfo = new Page<>(page, pageSize);

        //构建查询
        LambdaQueryWrapper<Order> orderQuery = new LambdaQueryWrapper<>();

        //查询用户名username是否为空
        if (username != null && !username.trim().isEmpty()) {

            //不为空即查询用户名的分页查询
            LambdaQueryWrapper<CustomerMembership> userQuery = new LambdaQueryWrapper<>();
            userQuery.eq(CustomerMembership::getName, username);

            log.info(username);

            CustomerMembership customerMembership = customerMembershipMapper.selectOne(userQuery);

            //正确查到用户项
            if (customerMembership != null) {
                orderQuery.eq(Order::getCustomerId, customerMembership.getCustomerId());
            } else {
                return pageInfo;
            }
        }

        log.info("排序");
        //设置排序条件--根据订单的创建时间降序排列
        orderQuery.orderByDesc(Order::getCreateTime);
        Page<Order> orderPage = new Page<>(page, pageSize);
        orderMapper.selectPage(orderPage, orderQuery);

        //订单行数组构建
        List<OrderDTO> orderDTOList = orderPage.getRecords().stream().map(order -> {

            OrderDTO orderDTO = new OrderDTO();
            //对象拷贝
            BeanUtils.copyProperties(order, orderDTO);

            LambdaQueryWrapper<CustomerMembership> customerQuery = new LambdaQueryWrapper<>();
            customerQuery.eq(CustomerMembership::getCustomerId, order.getCustomerId());
            CustomerMembership customer = customerMembershipMapper.selectOne(customerQuery);

            if (customer != null) {
                orderDTO.setCustomerName(customer.getName());
            }
            return orderDTO;
        }).collect(Collectors.toList());

        //构建分页查询数据
        pageInfo.setRecords(orderDTOList);
        pageInfo.setCurrent(orderPage.getCurrent());
        pageInfo.setSize(orderPage.getSize());
        pageInfo.setTotal(orderPage.getTotal());
        pageInfo.setPages(orderPage.getPages());

        return pageInfo;
    }

    //管理端：根据状态对订单分页查询
    @Override
    public Page<OrderDTO> getOrdersByStatus(int page, int pageSize, Integer status) {

        log.info(status.toString());
        //构建分页查询page
        Page<OrderDTO> pageInfo = new Page<>(page, pageSize);

        //构建查询
        LambdaQueryWrapper<Order> orderQuery = new LambdaQueryWrapper<>();

        //根据status筛选订单项
        orderQuery.eq(Order::getStatus, status);

        //构建排序条件--根据订单的创建时间降序排序
        orderQuery.orderByDesc(Order::getCreateTime);

        Page<Order> orderPage = new Page<>(page, pageSize);

        orderMapper.selectPage(orderPage, orderQuery);

        //订单行数组构建
        List<OrderDTO> orderDTOList = orderPage.getRecords().stream().map(order -> {

            //orderDTO才是最终页面要展示的全部数据项
            OrderDTO orderDTO = new OrderDTO();
            //对象拷贝
            BeanUtils.copyProperties(order, orderDTO);

            //构建查询
            LambdaQueryWrapper<CustomerMembership> customerQuery = new LambdaQueryWrapper<>();
            customerQuery.eq(CustomerMembership::getCustomerId, order.getCustomerId());
            CustomerMembership customer = customerMembershipMapper.selectOne(customerQuery);

            if (customer != null) {
                orderDTO.setCustomerName(customer.getName());
            }
            return orderDTO;
        }).collect(Collectors.toList());

        //设置分页查询页面page值
        pageInfo.setRecords(orderDTOList);
        pageInfo.setCurrent(orderPage.getCurrent());
        pageInfo.setSize(orderPage.getSize());
        pageInfo.setTotal(orderPage.getTotal());
        pageInfo.setPages(orderPage.getPages());

        return pageInfo;
    }

    /**管理端：
     * 订单管理
     * 更新订单状态为2已查询
     * @param order
     * @return
     */
    @Override
    public R<String> updateOrderStatus(Order order) {

        // 根据id查出订单
        Order existingOrder = orderMapper.selectById(order.getId());

        if (existingOrder == null) {
            return R.error("订单不存在");
        }

        Integer currentStatus = existingOrder.getStatus();

        Integer newStatus;

        if (order.getStatus() == 1) {
            newStatus = 2;
        } else {
            newStatus = 0;
        }
        log.info(newStatus.toString());
        // 检查并更新订单状态
        if (currentStatus.equals(Order.SUBMITTED)) {
            return R.error("订单未支付，不能配送");

            // 设定订单状态其他情况下的输出
            // 订单已支付情况
        } else if (currentStatus.equals(Order.PAID)) {

            //判断新状态设置--默认要求1->2
            if (newStatus.equals(Order.FINISHED)) {

                // 更新订单状态
                existingOrder.setStatus(newStatus);

                // existingOrder.setCompleteTime(LocalDateTime.now());
                boolean updateResult = orderMapper.updateById(existingOrder) == 1;

                if (updateResult) {
                    return R.success("订单状态更新成功");
                } else {
                    return R.error("订单状态更新失败");
                }
            } else {
                return R.error("当前状态不允许操作");
            }

            // 订单已完成情况
        } else if (currentStatus.equals(Order.FINISHED)) {
            return R.error("订单已配送，无需再次配送");

            // 订单已评价情况
        } else if (currentStatus.equals(Order.REVIEWED)) {
            return R.error("订单已结束，无需配送");

        } else {
            return R.error("未知订单状态");
        }
    }



    /**管理端：
     * 订单管理--稍后再改
     * 查看订单详情
     * @param orderId
     */
    @Override
    public OrderDetailDTO getOrderDetails(Long orderId) {
        // 查询订单
        Order order = orderMapper.selectById(orderId);
        if (order == null) {
            return null;
        }

        // 查询用户信息
        CustomerMembership customerMembership = customerMembershipMapper.selectOne(
                new QueryWrapper<CustomerMembership>().eq("customer_id", order.getCustomerId())
        );
        if (customerMembership == null) {
            return null;
        }

        // 查询客户信息以获取手机号
        Customer customer = customerMapper.selectById(customerMembership.getCustomerId());
        if (customer == null) {
            return null;
        }

        // 根据order_id查询订单详情
        List<OrderDetail> orderDetails = orderDetailMapper.selectList(
                new QueryWrapper<OrderDetail>().eq("order_id", orderId)
        );

        // 构建订单详情DTO
        OrderDetailDTO orderDetailDTO = new OrderDetailDTO();

        //对象拷贝
        BeanUtils.copyProperties(order, orderDetailDTO);

        //新加属性赋值
        orderDetailDTO.setCustomerName(customerMembership.getName());
        orderDetailDTO.setCustomerPhone(customer.getPhoneNumber());
        orderDetailDTO.setOrderDetails(orderDetails);

        return orderDetailDTO;
    }

    /**管理端：
     * 获取各类订单数量以及总订单数量
     * @return int[] 依次返回已提交、已支付、已完成、已评价订单的数量以及总订单数量
     */
    public int[] getOrderStatusCount() {

        //构建订单数量数组
        int[] orderStatusCount = new int[5];
        orderStatusCount[0] = orderMapper.countByStatus(Order.SUBMITTED);
        orderStatusCount[1] = orderMapper.countByStatus(Order.PAID);
        orderStatusCount[2] = orderMapper.countByStatus(Order.FINISHED);
        orderStatusCount[3] = orderMapper.countByStatus(Order.REVIEWED);
        orderStatusCount[4] = orderMapper.countTotalOrders();

        //返回订单数量数组结果
        return orderStatusCount;
    }
}

